package org.example.myleet.Utils;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class Parser {

    public static char[][] parseBoard(String s) {
        List<List<String>> lists = JsonUtils.parse(s, List.class);
        List<char[]> subLists = new ArrayList<>(lists.size());
        for (List<String> list : lists) {
            char[] subList = new char[list.size()];
            int j = 0;
            for (String str : list) {
                subList[j++] = str.charAt(0);
            }
            subLists.add(subList);
        }
        char[][] result = new char[subLists.size()][0];
        int i = 0;
        for (char[] subList : subLists) {
            result[i++] = subList;
        }
        return result;
    }

    public static int[][] parse(String s) {
        List<List<Integer>> lists = JsonUtils.parse(s, List.class);
        List<int[]> subLists = new ArrayList<>(lists.size());
        for (List<Integer> list : lists) {
            if (null == list) {
                subLists.add(null);
            } else {
                int[] subList = new int[list.size()];
                int j = 0;
                for (int integer : list) {
                    subList[j++] = integer;
                }
                subLists.add(subList);
            }
        }
        int[][] result = new int[subLists.size()][0];
        int i = 0;
        for (int[] subList : subLists) {
            result[i++] = subList;
        }
        return result;
    }

    public static TreeNode parse(Integer[] input) {
        if (input.length < 1) {
            return null;
        }
        int idx = 0;
        TreeNode root = new TreeNode(input[idx++]);
        Queue<TreeNode> stack1 = new LinkedList<>();
        stack1.offer(root);
        Queue<TreeNode> stack2 = new LinkedList<>();
        while (idx < input.length) {
            while (!stack1.isEmpty()) {
                if (idx >= input.length) {
                    break;
                }
                TreeNode node = stack1.poll();
                if (input[idx] == null) {
                    node.left = null;
                } else {
                    node.left = new TreeNode(input[idx]);
                }
                ++idx;
                if (idx >= input.length) {
                    break;
                }
                if (input[idx] == null) {
                    node.right = null;
                } else {
                    node.right = new TreeNode(input[idx]);
                }
                ++idx;
                if (node.left != null) {
                    stack2.offer(node.left);
                }
                if (node.right != null) {
                    stack2.offer(node.right);
                }
            }
            Queue<TreeNode> t = stack1;
            stack1 = stack2;
            stack2 = t;
        }
        return root;
    }

    public static ListNode parseLinkedList(String input) {
        List<Integer> list = JsonUtils.parse(input, List.class);
        ListNode dummy = new ListNode(-1);
        ListNode cur = dummy;
        for (Integer i : list) {
            cur.next = new ListNode(i);
            cur = cur.next;
        }
        return dummy.next;
    }

    public static Node parseComplexNodeRoot(Integer[] arr) {
        if (arr.length < 1) {
            return null;
        }
        Node dummy = new Node(-1);
        int cursor = 0;
        Node cur = dummy;
        while (cursor < arr.length) {
            if (arr[cursor] != null) {
                cur.next = new Node(arr[cursor++]);
                cur.next.prev = cur;
                cur = cur.next;
            } else {
                ++cursor;
                break;
            }
        }
        Node root = dummy.next;
        root.prev = null;
        parseComplexNodeChildren(root, arr, cursor);
        return root;
    }

    private static void parseComplexNodeChildren(Node parent, Integer[] arr, int cursor) {
        if (cursor >= arr.length) {
            return;
        }
        Node dummy = new Node(-1);
        Node cur = dummy;
        boolean found = false;
        while (cursor < arr.length) {
            if (arr[cursor] == null) {
                ++cursor;
                if (found) {
                    break;
                }
                parent = parent.next;
            } else {
                found = true;
                cur.next = new Node(arr[cursor++]);
                cur.next.prev = cur;
                cur = cur.next;
            }
        }
        Node child = dummy.next;
        child.prev = null;
        parseComplexNodeChildren(child, arr, cursor);
        parent.child = child;
    }

    public static char[] parse(String[] s) {
        char[] result = new char[s.length];
        int i = 0;
        for (String s_ : s) {
            result[i++] = s_.charAt(0);
        }
        return result;
    }

    public static org.example.myleet.model.Node parseNChildrenTree(Integer[] input) {
        if (input.length == 0) {
            return null;
        }
        org.example.myleet.model.Node dummy = new org.example.myleet.model.Node(-1);
        Queue<org.example.myleet.model.Node> queue = new LinkedList<>();
        queue.offer(dummy);
        int i = 0;
        while (i < input.length) {
            int len = queue.size();
            for (int j = 0; j < len; ++j) {
                org.example.myleet.model.Node cur = queue.poll();
                if (null == cur.children) {
                    cur.children = new ArrayList<>();
                }
                Integer value = input[i];
                if (null == value) {
                    ++i;
                    continue;
                }
                while (null != value) {
                    org.example.myleet.model.Node child = new org.example.myleet.model.Node(value);
                    cur.children.add(child);
                    queue.offer(child);
                    ++i;
                    if (i >= input.length) {
                        break;
                    }
                    value = input[i];
                }
                if (i >= input.length) {
                    break;
                }
                ++i;
            }
        }
        return dummy.children.get(0);
    }
}
